import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'dart:developer' as developer;

/// 高德地图定位结果数据模型
class AmapLocationResult {
  final bool success;
  final double? latitude;
  final double? longitude;
  final double? accuracy;
  final double? altitude;
  final double? bearing;
  final double? speed;
  final int? timestamp;
  final String? address;
  final String? country;
  final String? province;
  final String? city;
  final String? district;
  final String? street;
  final String? streetNumber;
  final String? poiName;
  final String? aoiName;
  final String? provider;
  final int? locationType;
  final int? errorCode;
  final String? errorMessage;

  AmapLocationResult({
    required this.success,
    this.latitude,
    this.longitude,
    this.accuracy,
    this.altitude,
    this.bearing,
    this.speed,
    this.timestamp,
    this.address,
    this.country,
    this.province,
    this.city,
    this.district,
    this.street,
    this.streetNumber,
    this.poiName,
    this.aoiName,
    this.provider,
    this.locationType,
    this.errorCode,
    this.errorMessage,
  });

  factory AmapLocationResult.fromMap(Map<String, dynamic> map) {
    return AmapLocationResult(
      success: map['success'] ?? false,
      latitude: map['latitude']?.toDouble(),
      longitude: map['longitude']?.toDouble(),
      accuracy: map['accuracy']?.toDouble(),
      altitude: map['altitude']?.toDouble(),
      bearing: map['bearing']?.toDouble(),
      speed: map['speed']?.toDouble(),
      timestamp: map['timestamp']?.toInt(),
      address: map['address'],
      country: map['country'],
      province: map['province'],
      city: map['city'],
      district: map['district'],
      street: map['street'],
      streetNumber: map['streetNumber'],
      poiName: map['poiName'],
      aoiName: map['aoiName'],
      provider: map['provider'],
      locationType: map['locationType']?.toInt(),
      errorCode: map['errorCode']?.toInt(),
      errorMessage: map['errorMessage'],
    );
  }

  @override
  String toString() {
    if (success) {
      return 'AmapLocationResult(success: $success, lat: $latitude, lng: $longitude, address: $address, accuracy: ${accuracy}m)';
    } else {
      return 'AmapLocationResult(success: $success, errorCode: $errorCode, errorMessage: $errorMessage)';
    }
  }
}

/// 高德地图定位服务类（Flutter端）
/// 
/// 通过Platform Channel与原生Android高德定位服务通信
/// 学习MyApplication2项目的定位功能实现
class AmapLocationService extends GetxService {
  static AmapLocationService get to => Get.find();
  
  // Platform Channel
  static const MethodChannel _channel = MethodChannel('com.playtruly.amap_location');
  
  // 定位状态
  RxBool isLocationStarted = false.obs;
  RxBool isLocating = false.obs;
  
  // 最后一次定位结果
  Rx<AmapLocationResult?> lastLocationResult = Rx<AmapLocationResult?>(null);

  @override
  void onInit() {
    super.onInit();
    developer.log('🗺️ =============== AmapLocationService 初始化开始 ===============', name: 'AmapLocationService');
    developer.log('📱 Platform Channel 名称: ${_channel.name}', name: 'AmapLocationService');
    developer.log('🔧 初始状态: isLocationStarted=${isLocationStarted.value}, isLocating=${isLocating.value}', name: 'AmapLocationService');
    developer.log('🗺️ =============== AmapLocationService 初始化完成 ===============', name: 'AmapLocationService');
  }

  @override
  void onClose() {
    // 确保服务关闭时停止定位
    stopLocation();
    super.onClose();
    developer.log('🗑️ AmapLocationService 已关闭', name: 'AmapLocationService');
  }

  /// 开始定位（学习MyApplication2的高精度定位配置）
  /// 
  /// [isOnceLocation] 是否单次定位，默认true
  /// [timeout] 定位超时时间
  Future<AmapLocationResult?> startLocation({
    bool isOnceLocation = true,
    Duration? timeout,
  }) async {
    try {
      developer.log('🎯 =============== 开始高德定位 ===============', name: 'AmapLocationService');
      developer.log('📍 定位模式: ${isOnceLocation ? "单次定位" : "持续定位"}', name: 'AmapLocationService');
      developer.log('⏱️ 超时时间: ${timeout?.inSeconds ?? 30}秒', name: 'AmapLocationService');
      developer.log('🔍 当前服务状态检查:', name: 'AmapLocationService');
      developer.log('  📱 Platform Channel: ${_channel.name}', name: 'AmapLocationService');
      developer.log('  🔄 isLocating: ${isLocating.value}', name: 'AmapLocationService');
      developer.log('  ▶️ isLocationStarted: ${isLocationStarted.value}', name: 'AmapLocationService');
      
      if (isLocating.value) {
        developer.log('⚠️ 定位请求正在进行中，忽略重复请求', name: 'AmapLocationService');
        return null;
      }

      // 🔒 预检查定位权限（新增）
      developer.log('🔒 预检查定位权限...', name: 'AmapLocationService');
      final hasPermissions = await checkLocationPermissions();
      if (!hasPermissions) {
        developer.log('❌ 定位权限检查失败，无法开始定位', name: 'AmapLocationService');
        developer.log('💡 提示：请在系统设置中为应用授予位置权限', name: 'AmapLocationService');
        return AmapLocationResult(
          success: false,
          errorCode: 12,
          errorMessage: '缺少定位权限，请在应用设置中授予位置权限',
        );
      }
      developer.log('✅ 权限检查通过，继续执行定位', name: 'AmapLocationService');
      
      isLocating.value = true;
      
      // 调用原生定位方法
      final Map<String, dynamic> arguments = {
        'isOnceLocation': isOnceLocation,
      };
      
      developer.log('📞 准备调用原生定位方法:', name: 'AmapLocationService');
      developer.log('  📞 方法名: startLocation', name: 'AmapLocationService');
      developer.log('  📞 参数: $arguments', name: 'AmapLocationService');
      
      // 设置超时时间
      developer.log('⏰ 开始Platform Channel调用...', name: 'AmapLocationService');
      final locationFuture = _channel.invokeMethod('startLocation', arguments);
      final timeoutFuture = timeout != null 
          ? Future.delayed(timeout, () => throw TimeoutException('定位超时', timeout))
          : locationFuture;
      
      developer.log('⏰ 等待定位结果...', name: 'AmapLocationService');
      final result = await Future.any([locationFuture, timeoutFuture]);
      developer.log('📨 Platform Channel调用完成，结果类型: ${result.runtimeType}', name: 'AmapLocationService');
      developer.log('📨 定位结果数据内容: $result', name: 'AmapLocationService');
      
      Map<String, dynamic>? resultMap;
      
      // 处理不同的返回类型（和权限检查类似的问题）
      if (result is Map<String, dynamic>) {
        resultMap = result;
      } else if (result is Map) {
        // 处理泛型Map类型，转换为Map<String, dynamic>
        try {
          resultMap = Map<String, dynamic>.from(result);
          developer.log('✅ 成功转换泛型Map为Map<String, dynamic>', name: 'AmapLocationService');
        } catch (e) {
          developer.log('❌ 转换泛型Map失败: $e', name: 'AmapLocationService');
        }
      }
      
      if (resultMap != null) {
        final locationResult = AmapLocationResult.fromMap(resultMap);
        lastLocationResult.value = locationResult;
        
        if (locationResult.success) {
          isLocationStarted.value = true;
          developer.log('✅ 高德定位成功!', name: 'AmapLocationService');
          developer.log('📍 坐标: ${locationResult.latitude}, ${locationResult.longitude}', name: 'AmapLocationService');
          developer.log('🎯 精度: ${locationResult.accuracy}m', name: 'AmapLocationService');
          developer.log('📍 地址: ${locationResult.address}', name: 'AmapLocationService');
          developer.log('🏙️ 城市: ${locationResult.province} ${locationResult.city} ${locationResult.district}', name: 'AmapLocationService');
        } else {
          developer.log('❌ 高德定位失败: ${locationResult.errorMessage} (${locationResult.errorCode})', name: 'AmapLocationService');
        }
        
        return locationResult;
      } else {
        developer.log('❌ 定位返回数据格式错误，无法解析结果', name: 'AmapLocationService');
        developer.log('❌ 原始数据: $result (${result.runtimeType})', name: 'AmapLocationService');
        return AmapLocationResult(
          success: false,
          errorCode: -1,
          errorMessage: '定位返回数据格式错误',
        );
      }
      
    } on TimeoutException catch (e) {
      developer.log('⏱️ 定位超时: ${e.message}', name: 'AmapLocationService');
      return AmapLocationResult(
        success: false,
        errorCode: -2,
        errorMessage: '定位超时',
      );
    } on PlatformException catch (e) {
      developer.log('💥 Platform异常详情:', name: 'AmapLocationService');
      developer.log('   错误代码: ${e.code}', name: 'AmapLocationService');
      developer.log('   错误消息: ${e.message}', name: 'AmapLocationService');
      developer.log('   错误详情: ${e.details}', name: 'AmapLocationService');
      
      String errorMsg;
      if (e.code == 'MissingPluginException') {
        errorMsg = '高德定位插件未正确注册，请检查Android端配置';
      } else {
        errorMsg = e.message ?? 'Platform调用异常';
      }
      
      return AmapLocationResult(
        success: false,
        errorCode: e.code.isNotEmpty ? int.tryParse(e.code) ?? -3 : -3,
        errorMessage: errorMsg,
      );
    } catch (e) {
      developer.log('💥 定位异常详情: $e', name: 'AmapLocationService');
      developer.log('💥 异常类型: ${e.runtimeType}', name: 'AmapLocationService');
      
      return AmapLocationResult(
        success: false,
        errorCode: -4,
        errorMessage: '定位异常: $e',
      );
    } finally {
      isLocating.value = false;
      developer.log('🏁 =============== 高德定位结束 ===============', name: 'AmapLocationService');
    }
  }

  /// 停止定位
  Future<bool> stopLocation() async {
    try {
      developer.log('🛑 停止高德定位', name: 'AmapLocationService');
      
      final result = await _channel.invokeMethod('stopLocation');
      
      if (result is Map<String, dynamic> && result['success'] == true) {
        isLocationStarted.value = false;
        isLocating.value = false;
        developer.log('✅ 高德定位已停止', name: 'AmapLocationService');
        return true;
      } else {
        developer.log('⚠️ 停止定位可能失败', name: 'AmapLocationService');
        return false;
      }
      
    } on PlatformException catch (e) {
      developer.log('💥 停止定位Platform异常: ${e.message}', name: 'AmapLocationService');
      return false;
    } catch (e) {
      developer.log('💥 停止定位异常: $e', name: 'AmapLocationService');
      return false;
    }
  }

  /// 检查定位状态
  Future<bool> checkLocationStatus() async {
    try {
      final result = await _channel.invokeMethod('isLocationStarted');
      
      if (result is Map<String, dynamic>) {
        final isStarted = result['isStarted'] ?? false;
        isLocationStarted.value = isStarted;
        return isStarted;
      }
      
      return false;
    } catch (e) {
      developer.log('⚠️ 检查定位状态异常: $e', name: 'AmapLocationService');
      return false;
    }
  }

  /// 检查定位权限状态（新增）
  Future<bool> checkLocationPermissions() async {
    try {
      developer.log('🔍 检查定位权限状态...', name: 'AmapLocationService');
      
      final result = await _channel.invokeMethod('checkPermissions');
      
      developer.log('📨 Android端返回数据: $result (类型: ${result.runtimeType})', name: 'AmapLocationService');
      
      // 处理不同的返回类型
      if (result is Map<String, dynamic>) {
        final hasPermissions = result['hasPermissions'] ?? false;
        final message = result['message'] ?? '权限检查失败';
        
        developer.log('📋 权限检查结果: $hasPermissions', name: 'AmapLocationService');
        developer.log('📋 权限检查消息: $message', name: 'AmapLocationService');
        
        return hasPermissions;
      } else if (result is Map) {
        // 处理泛型Map类型
        final resultMap = Map<String, dynamic>.from(result);
        final hasPermissions = resultMap['hasPermissions'] ?? false;
        final message = resultMap['message'] ?? '权限检查失败';
        
        developer.log('📋 权限检查结果: $hasPermissions', name: 'AmapLocationService');
        developer.log('📋 权限检查消息: $message', name: 'AmapLocationService');
        
        return hasPermissions;
      } else if (result is bool) {
        // 直接返回boolean的情况（兼容处理）
        developer.log('📋 权限检查结果（boolean）: $result', name: 'AmapLocationService');
        return result;
      }
      
      developer.log('❌ 权限检查返回格式错误，数据内容: $result', name: 'AmapLocationService');
      return false;
    } catch (e) {
      developer.log('💥 检查定位权限异常: $e', name: 'AmapLocationService');
      return false;
    }
  }

  /// 格式化地址信息（简化版本）
  String formatAddress(String? address) {
    if (address == null || address.isEmpty) {
      return '位置信息不详';
    }
    
    // 简单的地址格式化
    return address.length > 50 ? '${address.substring(0, 50)}...' : address;
  }

  /// 获取精度描述
  String getAccuracyDescription(double? accuracy) {
    if (accuracy == null) return '精度未知';
    
    if (accuracy <= 5) {
      return '高精度';
    } else if (accuracy <= 20) {
      return '中等精度';
    } else if (accuracy <= 100) {
      return '低精度';
    } else {
      return '精度较差';
    }
  }

  /// 快速获取当前位置（单次定位，带超时）
  Future<AmapLocationResult?> getCurrentLocation({
    Duration timeout = const Duration(seconds: 10),
  }) async {
    return await startLocation(
      isOnceLocation: true,
      timeout: timeout,
    );
  }

  /// 检查定位结果是否有效
  bool isLocationValid(AmapLocationResult? result) {
    if (result == null || !result.success) return false;
    
    final lat = result.latitude;
    final lng = result.longitude;
    
    if (lat == null || lng == null) return false;
    
    // 检查坐标是否在中国境内（粗略检查）
    if (lat < 3.86 || lat > 53.55 || lng < 73.66 || lng > 135.05) {
      return false;
    }
    
    return true;
  }

  /// 逆地理编码：根据坐标获取详细地址信息
  /// 
  /// [latitude] 纬度
  /// [longitude] 经度
  /// [timeout] 超时时间，默认10秒
  /// 返回包含详细地址信息的AmapLocationResult
  Future<AmapLocationResult?> reverseGeocode(
    double latitude, 
    double longitude, {
    Duration timeout = const Duration(seconds: 10),
  }) async {
    try {
      developer.log('🌐 =============== 开始逆地理编码 ===============', name: 'AmapLocationService');
      developer.log('📍 目标坐标: $latitude, $longitude', name: 'AmapLocationService');
      
      // 参数验证
      if (latitude.isNaN || longitude.isNaN || 
          latitude < -90 || latitude > 90 || 
          longitude < -180 || longitude > 180) {
        developer.log('❌ 坐标参数无效', name: 'AmapLocationService');
        return AmapLocationResult(
          success: false,
          errorCode: -1,
          errorMessage: '坐标参数无效',
        );
      }

      // 预检查权限
      final hasPermissions = await checkLocationPermissions();
      if (!hasPermissions) {
        developer.log('❌ 逆地理编码权限检查失败', name: 'AmapLocationService');
        return AmapLocationResult(
          success: false,
          errorCode: 12,
          errorMessage: '缺少定位权限，无法进行逆地理编码',
        );
      }
      
      // 调用Android端逆地理编码方法
      final Map<String, dynamic> arguments = {
        'latitude': latitude,
        'longitude': longitude,
      };
      
      developer.log('📞 调用Android端逆地理编码方法...', name: 'AmapLocationService');
      developer.log('📞 参数: $arguments', name: 'AmapLocationService');
      
      final geocodingFuture = _channel.invokeMethod('reverseGeocode', arguments);
      final timeoutFuture = Future.delayed(timeout, () => throw TimeoutException('逆地理编码超时', timeout));
      
      final result = await Future.any([geocodingFuture, timeoutFuture]);
      developer.log('📨 逆地理编码返回结果: $result (类型: ${result.runtimeType})', name: 'AmapLocationService');
      
      Map<String, dynamic>? resultMap;
      
      // 处理返回结果类型
      if (result is Map<String, dynamic>) {
        resultMap = result;
      } else if (result is Map) {
        try {
          resultMap = Map<String, dynamic>.from(result);
          developer.log('✅ 成功转换逆地理编码结果为Map<String, dynamic>', name: 'AmapLocationService');
        } catch (e) {
          developer.log('❌ 转换逆地理编码结果失败: $e', name: 'AmapLocationService');
        }
      }
      
      if (resultMap != null) {
        final locationResult = AmapLocationResult.fromMap(resultMap);
        
        if (locationResult.success) {
          developer.log('✅ 逆地理编码成功!', name: 'AmapLocationService');
          developer.log('📍 坐标: ${locationResult.latitude}, ${locationResult.longitude}', name: 'AmapLocationService');
          developer.log('📍 详细地址: ${locationResult.address}', name: 'AmapLocationService');
          developer.log('🏙️ 行政区域: ${locationResult.province} ${locationResult.city} ${locationResult.district}', name: 'AmapLocationService');
        } else {
          developer.log('❌ 逆地理编码失败: ${locationResult.errorMessage} (${locationResult.errorCode})', name: 'AmapLocationService');
        }
        
        return locationResult;
      } else {
        developer.log('❌ 逆地理编码返回数据格式错误', name: 'AmapLocationService');
        return AmapLocationResult(
          success: false,
          errorCode: -1,
          errorMessage: '逆地理编码返回数据格式错误',
        );
      }
      
    } on TimeoutException catch (e) {
      developer.log('⏱️ 逆地理编码超时: ${e.message}', name: 'AmapLocationService');
      return AmapLocationResult(
        success: false,
        errorCode: -2,
        errorMessage: '逆地理编码超时',
      );
    } on PlatformException catch (e) {
      developer.log('💥 逆地理编码Platform异常: ${e.message}', name: 'AmapLocationService');
      return AmapLocationResult(
        success: false,
        errorCode: e.code.isNotEmpty ? int.tryParse(e.code) ?? -3 : -3,
        errorMessage: e.message ?? '逆地理编码Platform异常',
      );
    } catch (e) {
      developer.log('💥 逆地理编码异常: $e', name: 'AmapLocationService');
      return AmapLocationResult(
        success: false,
        errorCode: -4,
        errorMessage: '逆地理编码异常: $e',
      );
    } finally {
      developer.log('🏁 =============== 逆地理编码结束 ===============', name: 'AmapLocationService');
    }
  }
}

/// 超时异常类
class TimeoutException implements Exception {
  final String message;
  final Duration? duration;

  const TimeoutException(this.message, [this.duration]);

  @override
  String toString() => 'TimeoutException: $message';
}